#ifndef __M_USER_H__
#define __M_USER_H__

#include <iostream>
#include <unordered_map>
#include <memory>
#include <vector>
#include <mutex>
#include "Util.hpp"

namespace cloud
{
#define USER_FILE "./user.data"
    struct User
    {
        User()
        {
        }

        User(std::string name, std::string password, int year, int month, int day)
            : _name(name), _password(password), _year(year), _month(month), _day(day)
        {
        }

        std::string _name;     // 用户名
        std::string _password; // 密码
        int _year;             // 生日
        int _month;
        int _day;
        std::string _filename; // 备份文件地址
        std::string _Email;
    };
    class UserManager
    {
    public:
        static std::shared_ptr<UserManager> GetInstance()
        {
            if (_ptr == nullptr) // 防止频繁加锁
            {
                _mutex.lock();
                if (_ptr == nullptr) // 为空就创建
                {
                    _ptr = std::shared_ptr<UserManager>(new UserManager());
                }
            }
            return _ptr;
        }

        bool Find(const std::string &_Email, User *user) // 查找用户
        {
            pthread_rwlock_rdlock(&_rwlock);
            if (_manager.find(_Email) != _manager.end())
            {
                *user = _manager[_Email];
                pthread_rwlock_unlock(&_rwlock);
                return true;
            }
            pthread_rwlock_unlock(&_rwlock);
            return false;
        }

        std::string GetEmail(const std::string& name)
        {
            for(auto e : _manager)
            {
                if(e.second._name == name)
                {
                    return e.second._Email;
                }
            }
            return "";
        }

        void AddUser(User &user) // 添加新用户
        {
            pthread_rwlock_rdlock(&_rwlock);
            _manager[user._Email] = user;
            fs::create_directories(config::GetInstance()->GetBackDictory() + user._Email + "/");//创建压缩目录
            fs::create_directories(config::GetInstance()->GetPackDictory() + user._Email + "/");//创建备份目录
            pthread_rwlock_unlock(&_rwlock);
            storage();
        }

        void DeleteUser(User& user)
        {
            pthread_rwlock_rdlock(&_rwlock);
            _manager.erase(user._name);
            pthread_rwlock_unlock(&_rwlock);
            storage();
        }

        void ModifyUse(User& newuser)
        {
            pthread_rwlock_rdlock(&_rwlock);
            // User olduser = _manager[user._name];
            pthread_rwlock_unlock(&_rwlock);
        }

        void GetAll(std::vector<User> &item) // 读取处出来,再去更新,防止加锁时间太久
        {
            pthread_rwlock_rdlock(&_rwlock);
            for (const auto &use : _manager)
            {
                item.push_back(use.second);
            }
            pthread_rwlock_unlock(&_rwlock);
        }

        size_t size()
        {
            return _manager.size();
        }

        void storage() // 更新
        {
            Json::Value root;
            std::vector<User> item; // 读取全部
            GetAll(item);
            for (const auto &use : item)
            {
                Json::Value item;
                item["name"] = use._name;
                item["password"] = use._password;
                item["filename"] = use._filename;
                item["year"] = use._year;
                item["month"] = use._month;
                item["day"] = use._day;
                item["email"] = use._Email;
                root.append(item);
            }
            std::string message; // 序列化
            JsonUtil::Serialize(root, &message);
            FileUtil file(USER_FILE);
            file.SetContent(message);
        }

    private:
        UserManager()
        {
            pthread_rwlock_init(&_rwlock,nullptr);
            Init();
        }

        void Init() // 初始化
        {
            FileUtil file(USER_FILE);
            std::string message;
            file.GetContent(&message); // 读取文件内容
            Json::Value root;
            JsonUtil::UnSerialize(message, &root); // 反序列化
            for (int i = 0; i < root.size(); ++i)
            {
                User user;
                user._name = root[i]["name"].asString();
                user._password = root[i]["password"].asString();
                user._filename = root[i]["filename"].asString();
                user._year = root[i]["year"].asInt();
                user._month = root[i]["month"].asInt();
                user._day = root[i]["day"].asInt();
                user._Email = root[i]["email"].asString();
                _manager[user._Email] = user;
                fs::create_directories(config::GetInstance()->GetBackDictory() + user._Email + "/");//创建压缩目录
                fs::create_directories(config::GetInstance()->GetPackDictory() + user._Email + "/");//创建备份目录
            }
        };

    private:
        std::unordered_map<std::string, User> _manager;
        static std::mutex _mutex;
        static std::shared_ptr<UserManager> _ptr;
        pthread_rwlock_t _rwlock; // 读写锁
    };
    std::mutex UserManager::_mutex;
    std::shared_ptr<UserManager> UserManager::_ptr = std::shared_ptr<UserManager>(nullptr);
}

#endif
